﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace WindowsAPI
{
    public static partial class Mouse
    {
        public static class API
        {
            //[Serializable, StructLayout(LayoutKind.Explicit)]
            //private struct MOUSE_EVENT_RECORD
            //{
            //    [FieldOffset(0)]
            //    public POINTSHORT MousePosition;
            //    [FieldOffset(4)]
            //    public uint ButtonState;
            //    [FieldOffset(8)]
            //    public uint ControlKeyState;
            //    [FieldOffset(12)]
            //    public MouseEventFlags EventFlags;
            //}

            [Serializable, Flags]
            public enum MouseEventFlags : uint
            {
                Absolute = 0x00008000,
                Move = 0x00000001,
                LeftDown = 0x00000002,
                LeftUp = 0x00000004,
                RightDown = 0x00000008,
                RightUp = 0x00000010,
                MiddleDown = 0x00000020,
                MiddleUp = 0x00000040,
                XDown = 0x00000080,
                XUp = 0x00000100,
                Wheel = 0x00000800
            }

            public enum MouseEventDataXButtons : uint
            {
                None = 0x00000000,
                XButton1 = 0x00000001,
                XButton2 = 0x00000002
            }

            [Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] // For GetMouseMovePointsEx
            public struct MouseMovePoint
            {
                public int x;            //Specifies the x-coordinate of the mouse
                public int y;            //Specifies the x-coordinate of the mouse
                public int time;             //Specifies the time stamp of the mouse coordinate
                public IntPtr dwExtraInfo;        //Specifies extra information associated with this coordinate. 
            }


            [DllImport(User32.FileName)]
            public static extern void mouse_event(MouseEventFlags dwFlags, uint dx, uint dy, uint dwData,
               UIntPtr dwExtraInfo);

            [DllImport(User32.FileName)]
            public static extern void mouse_event(MouseEventFlags dwFlags, uint dx, uint dy, uint dwData,
              int dwExtraInfo);

            [DllImport(User32.FileName)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetCursorPos(out POINT Point);


            [Serializable]
            public enum Resolutionmode : uint
            {
                DispayPoints = 1,
                HighResolutionPoints = 2
            }

            public static int GetMouseMovePointsEx(ref MouseMovePoint lppt,
                out MouseMovePoint[] lpptBuf, int nBufPoints, Resolutionmode resolution)
            {
                lpptBuf = new MouseMovePoint[64];
                return GetMouseMovePointsEx((uint)(Marshal.SizeOf(typeof(MouseMovePoint))),
                    ref lppt, lpptBuf, nBufPoints, (uint)resolution);
            }

            [DllImport(User32.FileName)]
            static extern int GetMouseMovePointsEx(uint cbSize, [In] ref MouseMovePoint
               lppt, [Out] MouseMovePoint[] lpptBuf, int nBufPoints, uint resolution);
        }

        public static void Click(API.MouseEventFlags Flags, Point point)
        {
            API.mouse_event(Flags, (uint)point.X, (uint)point.Y, 0, 0);
        }

        public static void ClickLeft(Point point)
        {
            Click(API.MouseEventFlags.LeftDown, point);
            Click(API.MouseEventFlags.LeftUp, point);
        }

        public static void ClickRight(Point point)
        {
            Click(API.MouseEventFlags.RightDown, point);
            Click(API.MouseEventFlags.RightUp, point);
        }
    }
}
